﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace System.Windows
{
    using System.Windows.Controls;
    /// <summary>
    /// 用于树形绑定的视图模型
    /// </summary>
    public class TreeNodeItemModel : DependencyObject
    {
        public TreeNodeItemModel()
        {
            this.Children = new TreeNodeItemModelCollection(this);
        }

        protected internal TreeNodeItemModelCollection ownerCollection;

        /// <summary>
        /// 从当前节点所属集合中移除此节点
        /// </summary>
        public void Remove()
        {
            if (this.ownerCollection != null)
            {
                this.ownerCollection.Remove(this);
            }
        }

        /// <summary>
        /// 节点视图内容，用于在<see cref="ContentPresenter"/>中呈现。
        /// </summary>
        public object Content
        {
            get { return (object)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.Register("Content", typeof(object), typeof(TreeNodeItemModel), new PropertyMetadata(null));

        /// <summary>
        /// 关联的数据
        /// </summary>
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object), typeof(TreeNodeItemModel), new PropertyMetadata(null));
        /// <summary>
        /// 获取父级节点
        /// </summary>
        public TreeNodeItemModel Parent
        {
            get { return (TreeNodeItemModel)GetValue(ParentProperty); }
            internal set { SetValue(ParentPropertyKey, value); }
        }
        private static DependencyPropertyKey ParentPropertyKey = DependencyProperty.RegisterReadOnly("Parent", typeof(TreeNodeItemModel), typeof(TreeNodeItemModel), new PropertyMetadata(default(TreeNodeItemModel)));
        public static DependencyProperty ParentProperty = ParentPropertyKey.DependencyProperty;

        /// <summary>
        /// 是否展开
        /// </summary>
        public bool IsExpanded
        {
            get { return (bool)GetValue(IsExpandedProperty); }
            set { SetValue(IsExpandedProperty, value); }
        }

        public static readonly DependencyProperty IsExpandedProperty =
            DependencyProperty.Register("IsExpanded", typeof(bool), typeof(TreeNodeItemModel), new PropertyMetadata(default(bool)));

        /// <summary>
        /// 是否选中
        /// </summary>
        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        public static readonly DependencyProperty IsSelectedProperty =
            DependencyProperty.Register("IsSelected", typeof(bool), typeof(TreeNodeItemModel), new PropertyMetadata(default(bool)));



        public TreeNodeItemModelCollection Children
        {
            get { return (TreeNodeItemModelCollection)GetValue(ChildrenProperty); }
            private set { SetValue(ChildrenPropertyKey, value); }
        }
        private static DependencyPropertyKey ChildrenPropertyKey = DependencyProperty.RegisterReadOnly("Children", typeof(TreeNodeItemModelCollection), typeof(TreeNodeItemModel), new PropertyMetadata(default(TreeNodeItemModelCollection)));
        public static DependencyProperty ChildrenProperty = ChildrenPropertyKey.DependencyProperty;


        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property == DataProperty)
            {
                this.OnDataChanged();
            }
        }
        /// <summary>
        /// 在关联的数据改变后触发
        /// </summary>
        protected virtual void OnDataChanged()
        {

        }
    }

    public class TreeNodeItemModelCollection : Collections.ObjectModel.ObservableCollection<TreeNodeItemModel>
    {
        public TreeNodeItemModelCollection()
        {
            this.CollectionChanged += Children_CollectionChanged;
        }
        public TreeNodeItemModelCollection(TreeNodeItemModel owner) : this()
        {
            this.Owner = owner;
        }

        internal TreeNodeItemModel Owner;

        private void Children_CollectionChanged(object sender, Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.OldItems != null)
            {
                foreach (var item in e.OldItems)
                {
                    if (item is TreeNodeItemModel node)
                    {
                        node.Parent = null;
                        node.ownerCollection = null;
                    }
                }
            }
            if (e.NewItems != null)
            {
                foreach (var item in e.NewItems)
                {
                    if (item is TreeNodeItemModel node)
                    {
                        node.Parent = this.Owner;
                        node.ownerCollection = this;
                    }
                }
            }
        }
    }
}
